package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.mapper.ChannelMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.aliyun.GreenImageScan;
import com.heima.aliyun.GreenTextScan;
import com.heima.common.exception.CustException;
import com.heima.feigns.WemediaFeign;
import com.heima.feigns.ArticleFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.utils.common.SensitiveWordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {
    @Autowired
    WemediaFeign wemediaFeign;
    @Autowired
    GreenTextScan greenTextScan;
    @Autowired
    GreenImageScan greenImageScan;
    @Value("${file.oss.web-site}")
    private String webSite;

    @Override
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        //参数校验,判断文章ID是否为空
        //若为空前后端抛出异常
        if (wmNewsId == null) {
            log.error("待审核文章不存在");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "当前待审核状态文章ID不能为空");
        }
        //1.不为空，根据文章ID查询文章
        ResponseResult<WmNews> wmNewsResult = wemediaFeign.findById(wmNewsId);
        if (wmNewsResult.getCode().intValue() != 0) {
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR);
        }
        //1.1判断文章内容是否为空
        //获取文章内容
        WmNews wmNews = wmNewsResult.getData();
        if (wmNews == null) {
            log.error("待审核的文章内容不存在，文章ID：{}", wmNews.getId());
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断文章的状态

        //2 文章状态=4 人工审核通过，直接保存文章
        if (wmNews.getStatus().shortValue() == WmNews.Status.ADMIN_SUCCESS.getCode() && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            //保存数据
            publishArticle(wmNews);
            return;
        }
        //3 文章状态=8 审核通过 但是发布时间小于等于当前时间，直接保存文章
        if (wmNews.getStatus().shortValue() == WmNews.Status.SUCCESS.getCode() && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            publishArticle(wmNews);
            return;
        }
        //4 文章状态=1 待审核
        if (wmNews.getStatus().shortValue() == WmNews.Status.SUBMIT.getCode()) {
            // 抽取文章内容中的文本和图片
            Map<String, Object> contentAndImagesResult = handlerTextAndImages(wmNews);
            //参数校验
            //1 根据WmNes文章id查询文章
            //判断文章的状态
            //2 文章状态=4 人工审核通过，直接保存文章
            //3 文章状态=8 审核通过 但是发布时间小于等于当前时间，直接保存文章
            //4 文章状态=1 待审核
                //4.1 自管理敏感词审核
                boolean isSensitiveScan = handleSensitive((String) contentAndImagesResult.get("content"), wmNews);
                if (!isSensitiveScan) return;
            //4.2 阿里云审核文本内容
            boolean isTextScan = handleTextScan((String) contentAndImagesResult.get("content"), wmNews);
            if (!isTextScan) return;
            //4.3 阿里云图片审核
            boolean isPictureScan = handlePictureScan((List) contentAndImagesResult.get("images"), wmNews);
            if (!isPictureScan) return;
            }
        }




    private boolean handlePictureScan(List <String>images, WmNews wmNews) {
        //判断有无图片  没有则不用审核
        if (images == null || images.size() == 0) {
            return true;
        }
        boolean flag = true;
        try {
            Map map = greenImageScan.imageUrlScan(images);
            if (map.get("suggestion").equals("block")) {
                updateWmNew(wmNews, WmNews.Status.FAIL.getCode(), "图片有违规内容");
                flag = false;
            }
            //人工审核
            if (map.get("suggestion").equals("review")) {
                updateWmNew(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "图片中含有不确定内容");
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateWmNew(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "阿里云审核失败，转入人工审核");
        }
        return flag;
    }

    private boolean handleTextScan(String content, WmNews wmNews) {
        boolean flag = true;
        try {
            Map map = greenTextScan.greenTextScan(content);
            String suggestion = (String) map.get("suggestion");
            //suggestion
            switch (suggestion) {
                case "block":
                    flag = false;
                    updateWmNew(wmNews, WmNews.Status.FAIL.getCode(), "文本中含有敏感词汇");
                    break;
                case "review":
                    flag = false;
                    updateWmNew(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "文本内容需要人工审核");
                    break;
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("阿里云审核文章失败，跳转人工审核，e:{}",e);
            flag = false;
            updateWmNew(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "文本内容需要人工审核");
        }
        return flag;
    }


    @Autowired
    AdSensitiveMapper adSensitiveMapper;
    private boolean handleSensitive(String content, WmNews wmNews) {

        boolean flag = true;
        // 查询所有敏感词
        List<String> allSensitive = adSensitiveMapper.findAllSensitive();
        // 初始化 DFA搜索
        SensitiveWordUtil.initMap(allSensitive);
        // 匹配敏感词:将敏感词封装到map集合
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if (map.size() > 0) {
            flag = false;
            updateWmNew(wmNews, (short) 2, "文章中包含了敏感词：" + map);
        }
        return flag;
    }

    private void updateWmNew(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        ResponseResult responseResult = wemediaFeign.updateWmNews(wmNews);
        if (responseResult.getCode().intValue() != 0) {
            log.error("远程调用updateWmNew方法失败，参数：{}",wmNews);
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR, responseResult.getErrorMessage());
        }
    }




            //TODO 4.4 判断文章发布时间大于当前时间，修改状态8
            //TODO 5 保存文章相关数据
            //TODO 6 同步索引库
            //TODO 7 生成文章静态页面



        private Map<String, Object> handlerTextAndImages (WmNews wmNews){
            String content = wmNews.getContent();
            //判断文章内容
            if (StringUtils.isNotBlank(content) || content.length() > 10000) {
                log.error("文章内容为空或文章字数大于1000");
                CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "文章内容不合法");
            }
            //文章内容转换对象
            List<Map> contentList = JSON.parseArray(content, Map.class);

            //2 解析内容文本 Stream 流优化 --> String
            // 中美
            // 国家英语   美_hmtt_国？
            String contents = contentList.stream()
                    .filter(x -> x.get("type").equals("text"))
                    .map(y -> y.get("value").toString())
                    .collect(Collectors.joining("_"));

            // 文章标题 参与审核
            //String title = wmNews.getTitle();
            //contents = title + "_" + contents;
            contents = wmNews.getTitle() + "_" + contents;

            //解析图片内容
            List<String> images = contentList.stream()
                    .filter(x -> x.get("type").equals("images"))
                    .map(y -> y.get("value").toString())
                    .collect(Collectors.toList());
            //4 处理封面前缀 1.jpg 2.jpg
            String wmNewsImages = wmNews.getImages();
            if (StringUtils.isNotBlank(wmNewsImages)) {
                images.addAll(
                        Stream.of(wmNewsImages.split(","))
                                .map(x -> webSite + x)
                                .collect(Collectors.toList())
                );
            }
            //封装并返回结果
            HashMap<String, Object> mapResult = new HashMap<>();
            mapResult.put("content", contents);
            mapResult.put("images", images);
            return mapResult;
        }


    /**
     * 发布文章方法
     *
     * @param wmNews
     */
    @Autowired
    ArticleFeign articleFeign;
        private void publishArticle (WmNews wmNews){
            //1. 远程调用saveArticle 保存3张表的信息
            ResponseResult responseResult = saveArticle(wmNews);
            if (responseResult.getCode().intValue() != 0) {
                log.error("远程调用saveArticle方法保存失败", responseResult.getErrorMessage());
                CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR);
            }
            //2. 修改自媒体文章状态  9
            wmNews.setArticleId((Long) responseResult.getData());
            updateWmNew(wmNews, (short) 9, "发布成功");

            //TODO 3. 通知ES索引库 添加对应文章
        }


    @Autowired
    ChannelMapper channelMapper;
    private ResponseResult saveArticle(WmNews wmNews) {
            //TODO
        /**
         * 远程调用feign保存三张表信息
         * @param wmNews
         * @return
         */
        //1. 封装dto参数
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);
        // 如果之前没发布过  id为null 发布过为之前关联的articleId
        articleDto.setId(wmNews.getArticleId());
        articleDto.setLabels(wmNews.getLabels());
        // 设置频道信息
        if (wmNews.getChannelId() == null) {
            AdChannel adChannel = channelMapper.selectById(wmNews.getChannelId());
            articleDto.setChannelName(adChannel.getName());
        }
        // 0 普通文章
        articleDto.setFlag((byte) 0);
        // 自媒体用户id 用于在article服务中查询相关作者信息
        articleDto.setWmUserId(wmNews.getUserId());
        // 远程调用 article微服务保存3张表方法
        return articleFeign.saveArticle(articleDto);

    }
}

